
#include "CANInit.h"
#include "CANProcess.h"
#include "globalDef.h"
#include "debug_prt.h"
extern CanRxStruct_Typedef CANRxStr;

/****************************************

初始化CANx-CAN
input：CANx  : CAN0  CAN1
CANbaudrate  : 波特率 例如 500000-500k
CANFDbaudrate: FD波特率 
CANFD：        是否使能FD   ENABLE DISABLE

output:  
****************************************/
void InitCANx(uint32_t CANx,uint32_t CANbaudrate,uint32_t CANFDbaudrate,ControlStatus CANFD)//初始化CAN
{
	gd_CANxGPIO_init(CANx );
	CANx_Config(CANx,CANbaudrate,CANFDbaudrate,CANFD);
	#if _EN_L610Debug_def	//调试信息
	printf("\r\nInitCANx\r\n");
	#endif
}



/**********************************************************/
void gd_CANxGPIO_init(uint32_t CANx)
{
		rcu_periph_clock_enable(RCU_AF);
		
		if (CANx == CAN0)
		{
			rcu_periph_clock_enable(RCU_GPIOA);
			rcu_periph_clock_enable(RCU_CAN0);
			gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_12);
			gpio_init(GPIOA, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, GPIO_PIN_11);
			
			//RS
			rcu_periph_clock_enable(RCU_GPIOA);
			gpio_init(GPIOA, GPIO_MODE_OUT_OD, GPIO_OSPEED_2MHZ, GPIO_PIN_8);
			gpio_bit_reset(GPIOA,GPIO_PIN_8);//RS：0 work, 1 standby
			//gpio_bit_set(GPIOA,GPIO_PIN_8);//RS：0 work, 1 standby
			//power
			rcu_periph_clock_enable(RCU_GPIOB);
			gpio_init(GPIOB, GPIO_MODE_OUT_OD, GPIO_OSPEED_2MHZ, GPIO_PIN_12);
			gpio_bit_reset(GPIOB,GPIO_PIN_12);//0 power on; 1 power off
			//gpio_bit_set(GPIOB,GPIO_PIN_12);
		}
		else
		{
			rcu_periph_clock_enable(RCU_GPIOB);
			rcu_periph_clock_enable(RCU_CAN1);
			gpio_pin_remap_config(GPIO_CAN1_REMAP,ENABLE);
			
			gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6);
			gpio_init(GPIOB, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, GPIO_PIN_5);
			
			
			//RS
			rcu_periph_clock_enable(RCU_GPIOB);
			gpio_init(GPIOB, GPIO_MODE_OUT_OD, GPIO_OSPEED_2MHZ, GPIO_PIN_4);
			gpio_bit_reset(GPIOB,GPIO_PIN_4);	//RS: 0 work, 1 standby
			//gpio_bit_set(GPIOB,GPIO_PIN_4);	//RS: 0 work, 1 standby
			
			//power
			rcu_periph_clock_enable(RCU_GPIOB);
			gpio_init(GPIOB, GPIO_MODE_OUT_OD, GPIO_OSPEED_2MHZ, GPIO_PIN_7);
			gpio_bit_reset(GPIOB,GPIO_PIN_7);//0 power on; 1 power off
			//gpio_bit_set(GPIOB,GPIO_PIN_7);
		}
}

void CANx_Config(uint32_t CANx,uint32_t CANbaudrate,uint32_t CANFDbaudrate,ControlStatus CANFD)
{

    can_parameter_struct can_parameter;
    can_fdframe_struct can_fd_parameter; 
    can_fd_tdc_struct can_fd_tdc_parameter;  	
		CANRxStr.getpos  = 0;
		CANRxStr.savepos = 0;  
    can_struct_para_init(CAN_INIT_STRUCT, &can_parameter);
		if(CAN0 == CANx)
		{	
			can_deinit(CAN0);
		}else
		{
			can_deinit(CAN1);
    }
    can_parameter.time_triggered = DISABLE;
    can_parameter.auto_bus_off_recovery = ENABLE;
    can_parameter.auto_wake_up = DISABLE;
    can_parameter.auto_retrans = ENABLE;
    can_parameter.rec_fifo_overwrite = DISABLE;
    can_parameter.trans_fifo_order = DISABLE;
    can_parameter.working_mode = CAN_NORMAL_MODE;  
		if(CAN0 == CANx)
		{
    can_init(CAN0, &can_parameter);
		}else{
    can_init(CAN1, &can_parameter);
    }
		if(CAN0 == CANx)
		{
			can_frequency_set(CAN0, CANbaudrate);
		}else{
    /* config CAN1 baud rate */
			can_frequency_set(CAN1, CANbaudrate);
    }
	if(CANFD == ENABLE)
	{
		can_struct_para_init(CAN_FD_FRAME_STRUCT, &can_fd_parameter);
		can_fd_parameter.fd_frame = ENABLE;
		can_fd_parameter.excp_event_detect = ENABLE;
		can_fd_parameter.delay_compensation = ENABLE;
		can_fd_tdc_parameter.tdc_filter = 0x04; 
		can_fd_tdc_parameter.tdc_mode = CAN_TDCMOD_CALC_AND_OFFSET;
		can_fd_tdc_parameter.tdc_offset = 0x04;
		can_fd_parameter.p_delay_compensation = &can_fd_tdc_parameter;
		can_fd_parameter.iso_bosch = CAN_FDMOD_ISO;
		can_fd_parameter.esi_mode = CAN_ESIMOD_HARDWARE;

		
		if(CAN0 == CANx)
		{
			can_fd_init(CAN0, &can_fd_parameter);
			can_fd_frequency_set(CAN0, CANFDbaudrate);
		}
		else
		{
			can_fd_init(CAN1, &can_fd_parameter);
			can_fd_frequency_set(CAN1, CANFDbaudrate);
		}	
	}
	/*滤波器设置*/
	can_filter_config(CANx);
	
    /* configure CAN0 NVIC */
		if(CAN0 == CANx)
		{
			nvic_irq_enable(CAN0_RX0_IRQn, 0, 0);
			can_interrupt_enable(CAN0, CAN_INTEN_RFNEIE0);
		}
    /* configure CAN1 NVIC */
		else
		{
			nvic_irq_enable(CAN1_RX1_IRQn, 1, 0);		
			can_interrupt_enable(CAN1, CAN_INTEN_RFNEIE1);
		}
}
void GaoZhi_can_filter_mask_mode_init(uint32_t id, uint32_t mask, uint8_t format_fifo, uint16_t filter_number,uint8_t CAN_filtermode)
{
    can_filter_parameter_struct can_filter;
    
    /* Initialize the filter structure */
    can_struct_para_init(CAN_FILTER_STRUCT, &can_filter);
    
    /* filter config */
    can_filter.filter_number = filter_number;
    can_filter.filter_mode = CAN_filtermode;//列表模式
    can_filter.filter_bits = CAN_FILTERBITS_32BIT;//32位ID
    can_filter.filter_enable = ENABLE;
	can_filter.filter_fifo_number = format_fifo;
	if(id == 0)
	{
		
		id = 0x7ff;
	}
	if(mask == 0)
	{
		id = 0x7ff;
	}
	if(id&0x80000000)
	{
		id = id&0x1fffffff;
		/* configure EFID[28:13] */
		can_filter.filter_list_high = (uint16_t)id >> 13; 
		/* configure EFID[12:0] and frame format bit set */
		can_filter.filter_list_low = (0x00FFU & (uint16_t)(id << 3)) | (1U << 2);

		mask = mask&0x1fffffff;
		/* configure EFID[28:13] mask */
		can_filter.filter_mask_high = (uint16_t)mask >> 13;
		/* configure EFID[12:0] and frame format bit mask */
		/* both data and remote frames can be received */
		can_filter.filter_mask_low = (0x00FFU & (uint16_t)(mask << 3)) | (1U << 2); 		
	}
	else
	{
//		mask = 0x7ff;
		can_filter.filter_list_high = (uint16_t)id << 5;
		can_filter.filter_list_low = 0x0000U;	

		/* configure SFID[10:0] */

		/* configure SFID[10:0] mask */
		can_filter.filter_mask_high = (uint16_t)mask << 5;
		/* both data and remote frames can be received */
		can_filter.filter_mask_low = 0x0000U;		
	}
		
   can_filter_init(&can_filter);
}



void can_filter_list_mode_init(uint32_t id, uint32_t mask, can_format_fifo_enum format_fifo, uint16_t filter_number)
{
    can_filter_parameter_struct can_filter;
    can_struct_para_init(CAN_FILTER_STRUCT, &can_filter);
    can_filter.filter_number = filter_number;
    can_filter.filter_mode = CAN_FILTERMODE_LIST;
    can_filter.filter_bits = CAN_FILTERBITS_32BIT;
    can_filter.filter_enable = ENABLE;
    switch(format_fifo){
        case CAN_STANDARD_FIFO0:
            can_filter.filter_fifo_number = CAN_FIFO0;
            can_filter.filter_list_high = (uint16_t)id << 5;
            can_filter.filter_list_low = 0x0000U;
            can_filter.filter_mask_high = (uint16_t)mask << 5;
            can_filter.filter_mask_low = 0x0000U;
            break;
        case CAN_STANDARD_FIFO1:
            can_filter.filter_fifo_number = CAN_FIFO1;
            can_filter.filter_list_high = (uint16_t)id << 5;
            can_filter.filter_list_low =  0x0000U;
            can_filter.filter_mask_high = (uint16_t)mask << 5;
            can_filter.filter_mask_low = 0x0000U;
            break;
        case CAN_EXTENDED_FIFO0:
            can_filter.filter_fifo_number = CAN_FIFO0;
            can_filter.filter_list_high = (uint16_t)(id >> 13);
            can_filter.filter_list_low = ((uint16_t)(id << 3)) | (1U << 2);
            can_filter.filter_mask_high = (uint16_t)(mask >> 13);
            can_filter.filter_mask_low = ((uint16_t)(mask << 3)) | (1U << 2);
            break;
        case CAN_EXTENDED_FIFO1:
            can_filter.filter_fifo_number = CAN_FIFO1;
            can_filter.filter_list_high = (uint16_t)(id >> 13);
            can_filter.filter_list_low = ((uint16_t)(id << 3)) | (1U << 2);
            can_filter.filter_mask_high = (uint16_t)(mask >> 13);
            can_filter.filter_mask_low = ((uint16_t)(mask << 3)) | (1U << 2);
            break;
        default:
				break;
    }
    can_filter_init(&can_filter);
}
/*
CAN 休眠
*/
void CAN_Sleep(u32 CANx)
{
	//CAN 0
	if(CANx == CAN0)
	{
		gpio_bit_set(GPIOA,GPIO_PIN_8);//RS：0 work, 1 standby
	}
	else	//CAN1
	{
		gpio_bit_set(GPIOB,GPIO_PIN_4);	//0 work, 1 standby
	}
}

/*
CAN 唤醒
*/
void CAN_Wakeup(u32 CANx)
{
	//CAN 0
	if(CANx == CAN0)
	{
		gpio_bit_reset(GPIOA,GPIO_PIN_8);//RS：0 work, 1 standby
	}
	else 	//CAN 1
	{
		gpio_bit_reset(GPIOB,GPIO_PIN_4);	//0 work, 1 standby
	}
}

/*
CAN 上电
*/
void CAN_poweron(u32 CANx)
{
	//CAN 0
	if(CANx == CAN0)
	{
		gpio_bit_reset(GPIOB,GPIO_PIN_12);//0 power on; 1 power off
	}
	else	//CAN1
	{
		gpio_bit_reset(GPIOB,GPIO_PIN_7);	//0 power on; 1 power off
	}
}

/*
CAN 下电
*/
void CAN_poweroff(u32 CANx)
{
	//CAN 0
	if(CANx == CAN0)
	{
		gpio_bit_set(GPIOB,GPIO_PIN_12);//0 power on; 1 power off
	}
	else 	//CAN 1
	{
		gpio_bit_set(GPIOB,GPIO_PIN_7);	//0 power on; 1 power off
	}
}

